package com.zhx.sweet.authentication.encrypt;

import com.zhx.sweet.encrypt.EncryptUserDetailService;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.InternalAuthenticationServiceException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;

/**
 * 主要是做认证的
 * @author zhanghaixuan
 * @create 2018年06月30日16:02:54
 **/
public class EncryptAuthenticationProvider implements AuthenticationProvider {

    private EncryptUserDetailService userDetailsService;

    /**
     * authentication中包含了用户信息
     * @param authentication
     * @return
     * @throws AuthenticationException
     */
    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        //重新包装 authentication
        EncryptAuthenticationToken encryptAuthenticationToken =(EncryptAuthenticationToken) authentication;

        //在用户管理中查找人
        String encrypt = (String) encryptAuthenticationToken.getPrincipal();

        try{
            UserDetails user = userDetailsService.loadUserByEncrypt(encrypt);

            if (user == null) {
                throw new InternalAuthenticationServiceException("无法获取用户信息");
            }
            //认证通过
            EncryptAuthenticationToken authenticationResult = new EncryptAuthenticationToken(user,user.getAuthorities());

            authenticationResult.setDetails(encryptAuthenticationToken.getDetails());

            return authenticationResult;
        }catch(UsernameNotFoundException ex){
            throw ex;
        }catch(BadCredentialsException ex){
            throw ex;
        }catch(Throwable ex){
            throw ex;
        }finally {

        }
    }

    @Override
    public boolean supports(Class<?> authentication) {
        return EncryptAuthenticationToken.class.isAssignableFrom(authentication);
    }

    public EncryptUserDetailService getUserDetailsService() {
        return userDetailsService;
    }

    public void setUserDetailsService(EncryptUserDetailService userDetailsService) {
        this.userDetailsService = userDetailsService;
    }
}
